﻿using RpcClient;
using RpcHelper;
using RpcModel;
using Wedonek.RpcStore.Gateway.Interface;
using Wedonek.RpcStore.Gateway.Model;
using Wedonek.RpcStore.Service.Interface;
using Wedonek.RpcStore.Service.Model;

namespace Wedonek.RpcStore.Gateway.Service
{
    internal class ServerService : IServerService
    {
        private readonly IServerCollect _Server = null;
        private readonly IServerTypeCollect _ServerType = null;
        private readonly IServerGroupCollect _Group = null;
        public ServerService(IServerCollect server, IServerTypeCollect serverType, IServerGroupCollect group)
        {
            this._Group = group;
            this._ServerType = serverType;
            this._Server = server;
        }

        public long Add(ServerConfigAddParam add)
        {
            this._Server.CheckServerPort(add.ServerMac, add.ServerPort);
            return this._Server.Add(add);
        }

        public void Drop(long id)
        {
            ServerConfigDatum config = this._Server.Get(id);
            if (config.IsOnline)
            {
                throw new ErrorException("rpc.server.not.allow.drop");
            }
            this._Server.Delete(config);
        }

        public RemoteServerDatum Get(long id)
        {
            ServerConfigDatum config = this._Server.Get(id);
            ServerGroup group = this._Group.GetGroup(config.GroupId);
            ServerType type = this._ServerType.Get(config.SystemType);
            return config.ConvertMap<ServerConfigDatum, RemoteServerDatum>((a, b) =>
            {
                b.GroupName = group.GroupName;
                b.SystemName = type.SystemName;
                b.BalancedType = type.BalancedType.ToString();
                return b;
            });
        }
        public void SetServiceState(long id, RpcServiceState state)
        {
            ServerConfigDatum config = this._Server.Get(id);
            this._Server.SetState(config, state);
        }

        public RemoteServer[] Query(QueryServiceParam query, IBasicPage paging, out long count)
        {
            ServerConfigDatum[] servers = this._Server.Query(query, paging, out count);
            if (servers.Length == 0)
            {
                return System.Array.Empty<RemoteServer>();
            }
            ServerType[] types = this._ServerType.Gets(servers.ConvertAll(c => c.SystemType));
            return servers.ConvertMap<ServerConfigDatum, RemoteServer>((a, b) =>
            {
                ServerType type = types.Find(c => c.Id == a.SystemType);
                b.SystemName = type.SystemName;
                b.BalancedType = type.BalancedType.ToString();
                return b;
            });
        }

        public void SetService(long id, ServerConfigSetParam set)
        {
            ServerConfigDatum config = this._Server.Get(id);
            if (config.IsOnline)
            {
                throw new ErrorException("rpc.server.not.allow.drop");
            }
            this._Server.Set(config, set);
        }
    }
}
